package lk.icta.core.dao;

import lk.icta.common.entity.DSDivision;
import lk.icta.core.entity.AlienationMethod;
import lk.icta.core.entity.LandApplication;
import lk.icta.core.entity.WorkflowTask;
import lk.icta.user.entity.User;

import java.util.Date;
import java.util.EnumSet;
import java.util.List;

/**
 * @author Tharanga Punchihewa
 */
public interface LandApplicationDAO {
    /**
     * Add a Land Application
     *
     * @param landApplication The Land Application to be added
     * @param user            User requesting to add the Land Application
     */
    public void addLandApplication(LandApplication landApplication, User user);

    /**
     * Update  a Land Application
     *
     * @param landApplication The Land Application to be updated
     * @param user            User requesting to add the Land Application
     */
    public void updateLandApplication(LandApplication landApplication, User user);

    /**
     * get  a Land Application  by application idUKey
     *
     * @param id   The Land Application id
     * @param user User requesting to add the Land Application
     */
    public LandApplication getLandApplicationByIdUKey(long id, User user);

    /**
     * Find Application List to be marked as completed
     *
     * @param user  User who perform this action
     * @param state State of the Land Application
     * @return The list of land applications to be completed
     */
    public List<LandApplication> getApplicationsByState(User user, WorkflowTask state);

    public List<LandApplication> getApplicationsByStateAndDistrict(User user, WorkflowTask state, int districtId);

    public List<LandApplication> getApplicationsByWorkFlowItemId(User user, int itemId);

    public List<LandApplication> getInitialApplicationsByState(User user, LandApplication.State state);

    public List<LandApplication> getApplicationsByWorkItemList(User user, List<Integer> workItemList);

    public List getPendingApplicationsCountByWorkflowTask(User user, List<Integer> workItemList);

    public List<LandApplication> getPendingApplicationsByWorkflowTask(User user, List<Integer> workItemList);

    public List<LandApplication> getPendingApplicationsByWorkflowTaskByAlienationMethod(User user, List<Integer> workItemList, int alienationMethodId);

    public List<LandApplication> getApplicationsByStates(User user, EnumSet<WorkflowTask> stateSet);

    public List<LandApplication> getApplicationsByStatesGn(User user, int gnId, EnumSet<WorkflowTask> stateSet);

    public List<LandApplication> getApplicationsByStateAndAM(User user, LandApplication.State state, int alienationType);

    public List<LandApplication> getShortListedCandidates(EnumSet<WorkflowTask> stateSet, int alienationMethod);

    //public List<LandApplication> getApplicationsByStateSet(User user, WorkflowTask state1, WorkflowTask state2);

    public List<LandApplication> getApplicationsByStateAndRole(User user, WorkflowTask state);

    public List<LandApplication> getApplicationsByWorkflowTask(User user, WorkflowTask state);

    /**
     * Find Ranked Application List to be marked as completed
     *
     * @param user  User who perform this action
     * @param state State of the Land Application
     * @return The list of land applications to be completed
     */
    public List<LandApplication> getRankedApplicationsByState(User user, LandApplication.State state);

    /**
     * Find the list of applications by workflow state
     *
     * @param user         User who perform this action
     * @param workflowTask The workflow state of the Alienation method of the Land Application
     * @return The List of land applications corresponding to the workflow state
     */
    public List<LandApplication> getApplicationsByWorkflowState(User user, WorkflowTask workflowTask);


    /**
     * Find the list of applications by workflow state
     *
     * @param alienationType type of the alienation
     * @return The List of land initial  applications
     */
    public List<LandApplication> getLandApplicationListByAlienationType(int alienationType, User user);

    /**
     * Find the list of applications by workflow state
     *
     * @param alienationType type of the alienation
     * @return The List of land initial  applications
     */
    public List<LandApplication> getSelectedLandApplicationListByAlienationType(int alienationType, User user);

    /**
     * Find the list of applications
     *
     * @return The List of land   applications
     */
    public List<LandApplication> getApplicationList(User user);

    /**
     * Search application of the DSDivision by person Name
     *
     * @param personName Name of the application to filter
     * @param user       User requesting to filter lands
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchApplicationsOfDSDivisionByPersonName(String personName, User user);

    /**
     * Search application of the DSDivision by NIC
     *
     * @param nic  NIC of the application to filter
     * @param user User requesting to filter lands
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchApplicationsOfDSDivisionByNIC(String nic, User user);

    /**
     * Search application of the DSDivision by Ds Id          *
     *
     * @param dsDivisionId Id of the D.S.Division
     * @param user         User requesting to filter lands
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchApplicationsByDsId(int dsDivisionId, User user);

    /**
     * Search application of the DSDivision by Ds List          *
     *
     * @param districtId Id of the D.S.Division
     * @param user       User requesting to filter lands
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchApplicationsByDistrictId(int districtId, User user);

    public List<LandApplication> getApplicationsByStateSetAndUser(User user);

    public List<LandApplication> getApplicationsByUser(User user);

    public List<LandApplication> getApplicationsByProvinceForSlcUsers(int provinceId);

    /**
     * Get applications by the WorkFlowTask State and by the DSDivision Id          *
     *
     * @param state        WorkFlowTask state of the land application
     * @param dsDivisionId Id of the D.S.Division
     * @param user         User requesting to filter lands
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> getApplicationsByStateAndDsId(WorkflowTask state, int dsDivisionId, User user);

    /**
     * Search applications by person Name
     *
     * @param holderName of the application to filter
     * @param user       requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchAlienationsByPersonName(String holderName, User user, WorkflowTask state);

    /**
     * Search application of the DSDivision by person Name
     *
     * @param holderNIC of the application to filter
     * @param user      requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchAlienationsByPersoNIC(String holderNIC, User user, WorkflowTask state);

    /**
     * Search application of the DSDivision by person Name
     *
     * @param alienationSerialNumber of the application to filter
     * @param user                   requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */

    public List<LandApplication> searchAlienationsByAlienationSerialNumber(long alienationSerialNumber, User user, WorkflowTask state);

    /**
     * Search application by land serial number
     *
     * @param landSerialNumber of the application to filter
     * @param user             requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchAlienationsByLnadSerialNumber(long landSerialNumber, User user, WorkflowTask state);

    /**
     * Search applications by alienation number
     *
     * @param alienationNumber of the application to filter
     * @param user             requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchAlienationByAlienationReferenceNumber(String alienationNumber, User user, WorkflowTask state);

    /**
     * Search application by alienation method
     *
     * @param alienationMethodId of the application to filter
     * @param user               requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchAlienationsByAlienationMethodId(int alienationMethodId, User user, WorkflowTask state);

    /**
     * Search application by alienation method
     *
     * @param user  requesting to filter lands
     * @param state
     * @return List of applications match the filtering criteria.
     */
    public List<LandApplication> searchAllAlienationsByAlienationMethodId(User user, WorkflowTask state);

    public List<Object[]> getLandApplicationStatistics(int id, String searchBy, int initAppState, int wftState, Date fromDate, Date toDate, String language);
}
